#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2025/11/2 16:00
# @Author  : summer
# @Email   : 610658552@qq.com
# @File    : ser_wechat.py
# @Software: PyCharm
# @Desc    : 微信公众号模板消息发送序列化器
from rest_framework import serializers


class WechatTemplateSendSerializer(serializers.Serializer):
    """
    微信公众号模板消息发送序列化器：
    1. 支持两种方式指定接收者：传phone（自动查openid）或直接传openid
    2. 校验模板变量格式（需符合微信要求：{"字段名": {"value": "内容", "color": "颜色"}}）
    """
    # 方式1：手机号（二选一，会自动关联WechatOpenid表查openid）
    phone = serializers.CharField(
        required=False,
        allow_blank=True,
        error_messages={
            "invalid": "手机号格式错误，应为字符串"
        }
    )
    # 方式2：直接传openid（二选一，优先级高于phone）
    openid = serializers.CharField(
        required=False,
        allow_blank=True,
        error_messages={
            "invalid": "openid格式错误，应为字符串"
        }
    )
    # 模板变量（必填，需符合微信模板格式）
    send_data = serializers.DictField(
        required=True,
        error_messages={
            "required": "模板变量为必填参数",
            "invalid": "模板变量必须为字典类型（格式：{\"字段名\": {\"value\": \"内容\"}}）"
        }
    )
    # 可选：点击模板消息跳转的H5链接
    url = serializers.URLField(
        required=False,
        allow_blank=True,
        error_messages={
            "invalid": "跳转链接格式错误，需为合法URL（如https://www.example.com）"
        }
    )
    # 可选：点击跳转的小程序配置（字典格式：{"appid": "小程序ID", "pagepath": "页面路径"}）
    miniprogram = serializers.DictField(
        required=False,
        default={},  # 移除allow_blank=True
        error_messages={
            "invalid": "小程序配置必须为字典类型（格式：{\"appid\": \"xxx\", \"pagepath\": \"xxx\"}"
        }
    )

    def validate(self, data):
        """
        全局校验：确保phone和openid二选一，且模板变量格式合法
        """
        phone = data.get("phone", "").strip()
        openid = data.get("openid", "").strip()
        send_data = data.get("send_data", {})
        miniprogram = data.get("miniprogram", {})

        # 1. 校验接收者：phone和openid必须填一个
        if not phone and not openid:
            raise serializers.ValidationError("必须填写「手机号」或「openid」中的一个")

        # 2. 若填了phone，校验手机号格式（11位数字）
        if phone and (not phone.isdigit() or len(phone) != 11):
            raise serializers.ValidationError(f"手机号 {phone} 格式错误，应为11位数字")

        # 3. 校验模板变量格式：每个字段必须包含"value"键（color可选）
        for field_name, field_val in send_data.items():
            if not isinstance(field_val, dict) or "value" not in field_val:
                raise serializers.ValidationError(
                    f'模板变量「{field_name}」格式错误，需包含"value"键 如：{"{field_name}": {"value": "内容"}}')
            # 校验value值不为空
            if not str(field_val["value"]).strip():
                raise serializers.ValidationError(f"模板变量「{field_name}」的\"value\"不能为空")

        # 4. 若填了小程序配置，校验必须包含appid和pagepath
        if miniprogram and (not miniprogram.get("appid") or not miniprogram.get("pagepath")):
            raise serializers.ValidationError("小程序配置必须包含「appid」和「pagepath」字段")

        # 清洗数据：去除空字符串，避免后续处理异常
        if not phone:
            data.pop("phone", None)
        if not openid:
            data.pop("openid", None)
        if not data.get("url"):
            data.pop("url", None)
        if not miniprogram:
            data.pop("miniprogram", None)
        print(f'data === ',data)
        return data